package com.chenjiaru.util;

import lombok.extern.slf4j.Slf4j;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * YAML工具类
 */
@Slf4j
public class YamlUtil {
    private static Map<String, Map<String, Object>> basicMap = new ConcurrentHashMap<>();

    /**
     * 加载YAML文件
     * @param path
     * @return
     */
    public static Map<String, Object> loadFile(String path) {
        Map<String, Object> map = basicMap.get(path);
        if(map == null) {
            Yaml yaml = new Yaml();
            String newPath = removeJar(YamlUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath()) + path;
            if(new File(newPath).exists()) {
                try(InputStream inputStream = new FileInputStream(newPath)) {
                    basicMap.put(path, yaml.load(inputStream));
                    map = basicMap.get(path);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                try(InputStream inputStream = YamlUtil.class.getClassLoader().getResourceAsStream(path)) {
                    basicMap.put(path, yaml.load(inputStream));
                    map = basicMap.get(path);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return map;
    }

    /**
     * 删除路径中的jar
     * @param path
     * @return
     */
    public static String removeJar(String path) {
        String JAR = ".jar";
        if(path.contains(JAR)) {
            path = path.substring(0, path.lastIndexOf(JAR));
        } else {
            return path;
        }
        if(path.contains(JAR)) {
            return removeJar(path);
        }
        if(path.contains("file:")) {
            path = path.replace("file:", "");
        }
        return path.substring(0, path.lastIndexOf("/") + 1);
    }

    /**
     * 获取Object
     * @param path
     * @param keyArr
     * @return
     */
    public static Object getValue(String path, String...keyArr) {
        Object value = null;
        Map<String, Object> map = YamlUtil.loadFile(path);
        for(int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            value = map.get(key);
            if(value instanceof Map) {
                map = (Map<String, Object>)value;
            }
        }
        return value;
    }

    /**
     * 获取String
     * @param path
     * @param keyArr
     * @return
     */
    public static String getValueToString(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (String)value;
    }

    /**
     * 获取List
     * @param path
     * @param keyArr
     * @return
     */
    public static List<String> getValueToList(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (List<String>)value;
    }

    /**
     * 获取List
     * @param path
     * @param keyArr
     * @return
     */
    public static Map<String, Object> getValueToMap(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (Map<String, Object>)value;
    }

    /**
     * 获取Integer
     * @param path
     * @param keyArr
     * @return
     */
    public static Integer getValueToInteger(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (Integer)value;
    }

    /**
     * 获取Double
     * @param path
     * @param keyArr
     * @return
     */
    public static Double getValueToDouble(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (Double)value;
    }

    /**
     * 获取Long
     * @param path
     * @param keyArr
     * @return
     */
    public static Long getValueToLong(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (Long)value;
    }

    /**
     * 获取Boolean
     * @param path
     * @param keyArr
     * @return
     */
    public static Boolean getValueToBoolean(String path, String...keyArr) {
        Object value = getValue(path, keyArr);
        return value == null ? null : (Boolean)value;
    }
}
